﻿Imports TranslatorIO
Imports ShererTranslator
Imports AutoCompleteMenuNS
Imports ShererTranslator.MessageBox
Imports System.Text.RegularExpressions

Public Class MainWindow

#Region "Variables"
    Dim diff As Integer
    Dim actived As Boolean
    Dim working As Boolean
    Dim lighting As Boolean
    Dim dbEnumerable As Object
    Dim highlight As New Highlight
    Dim thread As Threading.Thread
    Dim menuThread As Threading.Thread
    Friend WithEvents FileSystem As FileSystem
    Friend WithEvents AutoCompleteMenu1 As New CustomAutoComplateMenu
#End Region

#Region "UI Language"
    Sub New()

#Region "This call is required by the designer."
        actived = False
        InitializeComponent()
        actived = True

        LanguagesToolStripMenuItem.DropDownItems.Clear()
        For Each Lan In Languages
            With LanguagesToolStripMenuItem.DropDownItems
                Dim item As New ToolStripMenuItem(
                     Lan.Value, Nothing,
                     New EventHandler(
                        Sub(sender, e)
                            If sender.Checked Then Return
                            Config.EditSetting("ui", "language", Lan.Key)
                            For Each item In LanguagesToolStripMenuItem.DropDownItems
                                item.Checked = (Lan.Key = item.Name)
                            Next

                            Dim temp As New iniFile($"Languages/{Lan.Key}.ini")
                            Dim title, content, ok, cancel As String, Options As MsgBoxOptions
                            Dim RightToLeftLayout As Boolean, TextFont, ButtonFont As Font

                            If FileSystem.IsEdit Then
                                ok = temp("message", "restart")
                                cancel = temp("message", "no_thanks")
                                title = temp("message_title", "restart")
                                content = temp("message_content", "restart_after_modify")
                                RightToLeftLayout = Val(temp("language", "rtl", "0"))
                                TextFont = New FontConverter().ConvertFromString(temp("fonts", "message"))
                                ButtonFont = New FontConverter().ConvertFromString(temp("fonts", "message_btn"))
                                Options = New MsgBoxOptions(RightToLeftLayout, TextFont, ButtonFont, ok, cancel)
                                If MsgBox(content, OkCancelDefault2, title, Options) = MsgBoxResult.Cancel Then
                                    Return
                                End If
                            ElseIf FileSystem.IsLoad Then
                                ok = temp("message", "restart")
                                cancel = temp("message", "no_thanks")
                                title = temp("message_title", "restart")
                                content = temp("message_content", "restart_after_open")
                                RightToLeftLayout = Val(temp("language", "rtl", "0"))
                                TextFont = New FontConverter().ConvertFromString(temp("fonts", "message"))
                                ButtonFont = New FontConverter().ConvertFromString(temp("fonts", "message_btn"))
                                Options = New MsgBoxOptions(RightToLeftLayout, TextFont, ButtonFont, ok, cancel)
                                If MsgBox(content, OkCancelDefault1, title, Options) = MsgBoxResult.Cancel Then
                                    Return
                                End If
                            End If
                            Application.Restart()
                        End Sub),
                     Lan.Key) With {.Checked = (Lan.Key = Config("ui", "language"))}
                .Add(item)
            End With
        Next

        ListBox1.DisplayMember = "Value"
        ListBox1.ValueMember = "Key"
        ListBox1.DataSource = New BindingSource(Languages, Nothing)

        ListBox1.SelectedValue = Config("ui", "language")

        With AutoCompleteMenu1
            .MaxItemCount = 25
            .ToolTipDuration = 30000
            .SetAutoCompleteMenu(RichTextBox2, AutoCompleteMenu1)
        End With
#End Region

#Region "Set fonts"
        Call SetFonts()

        Dim converter As New FontConverter
        Dim sourceFont As Font = converter.ConvertFromString(Config("settings", "source_font"))
        Dim targetFont As Font = converter.ConvertFromString(Config("settings", "target_font"))

        Me.RichTextBox1.Font = sourceFont
        Me.RichTextBox2.Font = targetFont
        AutoCompleteMenu1.Font = targetFont
        AutoCompleteMenu1.ToolTipFont = targetFont
        With targetFont
            AutoCompleteMenu1.ToolTipTitleFont = New Font(.FontFamily, .Size, FontStyle.Bold, .Unit)
        End With
#End Region

#Region "Set right to left"
        Me.RightToLeft = R2L
        Me.RightToLeftLayout = R2L
        Me.Panel2.Dock = 4 - R2L
        Me.Splitter1.Dock = 4 - R2L
        Me.ListView1.RightToLeftLayout = R2L
        Me.ContextMenuStrip1.RightToLeft = R2L
        Me.ContextMenuStrip2.RightToLeft = R2L
        Me.AutoCompleteMenu1.RightToLeft = R2L
#End Region

#Region "Set menu words"
        FileToolStripMenuItem.Text = Language("main_menu", "file")
        EditToolStripMenuItem.Text = Language("main_menu", "edit")
        ViewToolStripMenuItem.Text = Language("main_menu", "view")
        ToolsToolStripMenuItem.Text = Language("main_menu", "tools")
        GoToolStripMenuItem.Text = Language("main_menu", "go")
        DatabaseToolStripMenuItem.Text = Language("main_menu", "db")
        HelpToolStripMenuItem.Text = Language("main_menu", "help")
#End Region

#Region "Set menu-file words"
        OpenToolStripMenuItem.Text = Language("main_menu_file", "open")
        ImportToolStripMenuItem.Text = Language("main_menu_file", "import")
        SaveToolStripMenuItem.Text = Language("main_menu_file", "save")
        SaveAsToolStripMenuItem.Text = Language("main_menu_file", "save_as")
        SaveDataToolStripMenuItem.Text = Language("main_menu_file", "save_data")
        SettingsToolStripMenuItem.Text = Language("main_menu_file", "settings")
        RecentToolStripMenuItem.Text = Language("main_menu_file", "recent")
        ExitToolStripMenuItem.Text = Language("main_menu_file", "exit")
#End Region

#Region "Set menu-edit words"
        ClearTranslationToolStripMenuItem.Text = Language("main_menu_edit", "clear_translation")
        ClearAllTranslationToolStripMenuItem.Text = Language("main_menu_edit", "clear_all_translation")
        ClearAllUntranslationToolStripMenuItem.Text = Language("main_menu_edit", "clear_all_untranslation")
        CopyFromSourceTextToolStripMenuItem.Text = Language("main_menu_edit", "copy_source")
        CopyAllFromSourceTextToolStripMenuItem.Text = Language("main_menu_edit", "copy_all_source")
        CopyUntranslateFromSourceTextToolStripMenuItem.Text = Language("main_menu_edit", "copy_untranslate_source")
        SuggestionsToolStripMenuItem.Text = Language("main_menu_edit", "suggestions")
        FindToolStripMenuItem.Text = Language("main_menu_edit", "find")
        ReplaceToolStripMenuItem.Text = Language("main_menu_edit", "replace")
#End Region

#Region "Set menu-view words"
        ShowNoColumnToolStripMenuItem.Text = String.Format(Language("main_menu_view", "show_column"), Language("main_listview_column", "no"))
        ShowKeyColumnToolStripMenuItem.Text = String.Format(Language("main_menu_view", "show_column"), Language("main_listview_column", "key"))
        SortByFileOrderToolStripMenuItem.Text = Language("main_menu_view", "sort_by_file_order")
        SortBySourceToolStripMenuItem.Text = Language("main_menu_view", "sort_by_source")
        SortByTranslationToolStripMenuItem.Text = Language("main_menu_view", "sort_by_translation")
        ShowSlidebarToolStripMenuItem.Text = Language("main_menu_view", "show_slidebar")
        ShowStatusbarToolStripMenuItem.Text = Language("main_menu_view", "show_statusbar")
        ShowDictionaryToolStripMenuItem.Text = Language("main_menu_view", "show_dictionary")
        LanguagesToolStripMenuItem.Text = Language("main_menu_view", "languages")
#End Region

#Region "Set menu-tools words"
        TranslateAllFromLocalToolStripMenuItem.Text = Language("main_menu_tools", "translate_all")
        TranslateUntranslationsFromLocalToolStripMenuItem.Text = Language("main_menu_tools", "translate_untranslations")
        DictionaryToolStripMenuItem.Text = Language("main_menu_tools", "dictionary")
#End Region

#Region "Set menu-go words"
        DoneAndNextToolStripMenuItem.Text = Language("main_menu_go", "done_and_next")
        PreviousTranslationToolStripMenuItem.Text = Language("main_menu_go", "previous_translation")
        NextTranslationToolStripMenuItem.Text = Language("main_menu_go", "next_translation")
        PreviousUnfinishedToolStripMenuItem.Text = Language("main_menu_go", "previous_unfinished")
        NextUnfinishedToolStripMenuItem.Text = Language("main_menu_go", "next_unfinished")
#End Region

#Region "Set menu-database words"
        ExportToolStripMenuItem.Text = Language("main_menu_db", "export")
        ImportToolStripMenuItem1.Text = Language("main_menu_db", "import")
#End Region

#Region "Set menu-help words"
        AboutToolStripMenuItem.Text = Language("main_menu_help", "about")
#End Region

#Region "Set toolbar words"
        ToolStripButton3.Text = Language("main_tool", "open")
        ToolStripButton6.Text = Language("main_tool", "import")
        ToolStripButton7.Text = Language("main_tool", "save")
        ToolStripButton8.Text = Language("main_tool", "settings")
        ToolStripSplitButton1.Text = Language("main_tool", "translate")
        ToolStripButton9.Text = Language("main_tool", "dictionary")
        ToolStripButton10.Text = Language("main_tool", "show_slidebar")
#End Region

#Region "Set context menu words"
        ClearTranslationToolStripMenuItem1.Text = Language("main_context_menu", "clear_translation")
        CopyFromSourceTextToolStripMenuItem1.Text = Language("main_context_menu", "copy_source")
        SuggestionsToolStripMenuItem1.Text = Language("main_context_menu", "suggestions")

        CutToolStripMenuItem.Text = Language("main_context_menu", "cut")
        CopyToolStripMenuItem.Text = Language("main_context_menu", "copy")
        PasteToolStripMenuItem.Text = Language("main_context_menu", "paste")
        DeleteToolStripMenuItem.Text = Language("main_context_menu", "delete")
        SelectAllToolStripMenuItem.Text = Language("main_context_menu", "select_all")
        SearchWithGoogleToolStripMenuItem.Text = Language("main_context_menu", "search_with_google")
#End Region

#Region "Set listview words"
        ColumnNo.Text = Language("main_listview_column", "no")
        ColumnKey.Text = Language("main_listview_column", "key")
        ColumnSource.Text = Language("main_listview_column", "source")
        ColumnTarget.Text = Language("main_listview_column", "target")
#End Region

#Region "Set editor words"
        ToolStripLabel1.Text = Language("main_editor", "source")
        ToolStripLabel2.Text = Language("main_editor", "translation")
        ToolStripButton4.Text = Language("main_editor", "font")
        ToolStripButton5.Text = Language("main_editor", "font")
        ToolStripButton1.Text = Language("main_editor", "direction")
        ToolStripButton2.Text = Language("main_editor", "direction")
        ToolStripSplitButton2.Text = Language("main_editor", "insert")
        LefttorightMarkToolStripMenuItem.Text = Language("main_editor", "ltr_mark")
        RighttoleftMarkToolStripMenuItem.Text = Language("main_editor", "rtl_mark")
        LefttorightEmbeddingToolStripMenuItem.Text = Language("main_editor", "ltr_embedding")
        RighttoleftEmbeddingToolStripMenuItem.Text = Language("main_editor", "rtl_embedding")
#End Region

#Region "Set slidebar words"
        Label1.Text = Language("main_slidebar", "translation_suggestions")
        Label2.Text = Language("main_slidebar", "dictionary")
        Button1.Text = Language("main_slidebar", "search")
#End Region

    End Sub
    Private Sub ListBox1_DrawItem(sender As Object, e As DrawItemEventArgs) Handles ListBox1.DrawItem
        e.DrawBackground()
        e.DrawFocusRectangle()
        If e.Index = -1 Then Return
        Using sf As New StringFormat
            If sender.RightToLeft = RightToLeft.Yes Then sf.FormatFlags = StringFormatFlags.DirectionRightToLeft
            e.Graphics.DrawString(sender.Items(e.Index).value, e.Font, New SolidBrush(e.ForeColor), e.Bounds, sf)
        End Using
    End Sub
    Private Sub ListBox1_SelectedValueChanged(sender As Object, e As EventArgs) Handles ListBox1.SelectedValueChanged
        Dim value As Object = ListBox1.SelectedValue
        If value Is Nothing Then Return

        Dim lan As New iniFile($"Languages/{value}.ini")
        'TableLayoutPanel6.RightToLeft = If(Val(lan("language", "rtl", "0")) = 1, 1, 0)
        Label3.Text = lan("welcome", "title")
        Label4.Text = String.Format(lan("welcome", "version"), My.Application.Info.Version.ToString(3))
        Label5.Text = lan("welcome", "select_language")
        Button2.Text = lan("welcome", "save_and_restart")
    End Sub
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim value As Object = ListBox1.SelectedValue
        Dim lan As String = Config("ui", "language")
        If value Is Nothing OrElse value = lan Then Return
        Config.EditSetting("ui", "language", value)
        Application.Restart()
    End Sub
#End Region

#Region "Functions"
    ''' <summary>
    ''' Set layout fonts
    ''' </summary>
    Private Sub SetFonts()
        Dim converter As New FontConverter
        Dim generalFont As Font = converter.ConvertFromString(Language("fonts", "general"))
        Dim smallFont As Font = converter.ConvertFromString(Language("fonts", "small"))
        Dim titleFont As Font = converter.ConvertFromString(Language("fonts", "title"))
        Dim menuFont As Font = converter.ConvertFromString(Language("fonts", "menu"))
        Dim welcomeFont As Font = converter.ConvertFromString(Language("fonts", "welcome"))
        Dim welcomelargeFont As Font = converter.ConvertFromString(Language("fonts", "welcome_large"))
        Dim welcomeSmallFont As Font = converter.ConvertFromString(Language("fonts", "welcome_small"))

        Me.Font = generalFont
        Me.Label1.Font = titleFont
        Me.Label2.Font = titleFont
        Me.MenuStrip1.Font = menuFont
        Me.ToolStrip1.Font = menuFont
        Me.ToolStrip2.Font = menuFont
        Me.ToolStrip3.Font = menuFont
        Me.StatusStrip1.Font = menuFont
        Me.ContextMenuStrip1.Font = menuFont
        Me.ContextMenuStrip2.Font = menuFont
        Me.SuggestList1.TagFont = smallFont
        Me.TableLayoutPanel6.Font = welcomeFont
        Me.Label3.Font = welcomelargeFont
        Me.Label4.Font = welcomeSmallFont
    End Sub
    ''' <summary>
    ''' Show recent list on file menu
    ''' </summary>
    Private Sub ShowRecent()
        RecentToolStripMenuItem.DropDownItems.Clear()
        For Each file In Recent
            If Trim(file) = "" Then Continue For
            With RecentToolStripMenuItem.DropDownItems
                Dim item As New ToolStripMenuItem(
                     file, Nothing,
                     New EventHandler(
                        Sub(sender, e)
                            If file = FileSystem.OpenFile.Path Then Return

                            Dim title, content, ok, cancel As String
                            If Not IO.File.Exists(file) Then
                                title = Language("message_title", "file_error")
                                content = String.Format(Language("message_content", "file_not_exist"), file)

                                MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)

                                Recent.Remove(file)
                                Config.EditSetting("info", "recent", Join(Recent.ToArray, "|"))
                                Call ShowRecent()
                                Return
                            ElseIf FileSystem.IsEdit Then
                                title = Language("message_title", "open_file")
                                content = Language("message_content", "open_file_after_modify")
                                ok = Language("message", "open_file")
                                cancel = Language("message", "no_thanks")

                                If MsgBox(content, OkCancelDefault2, title, New MsgBoxOptions(MsgBoxOptions, ok, cancel)) = MsgBoxResult.Cancel Then
                                    Return
                                End If
                            ElseIf FileSystem.IsLoad Then
                                title = Language("message_title", "open_file")
                                content = Language("message_content", "open_file_after_open")
                                ok = Language("message", "open_file")
                                cancel = Language("message", "no_thanks")

                                If MsgBox(content, OkCancelDefault1, title, New MsgBoxOptions(MsgBoxOptions, ok, cancel)) = MsgBoxResult.Cancel Then
                                    Return
                                End If
                            End If

                            FileSystem.Open(file)
                            Call Open()
                        End Sub),
                     file)

                .Add(item)
            End With
        Next

        ToolStripButton3.DropDownItems.Clear()
        For Each file In Recent
            If Trim(file) = "" Then Continue For
            With ToolStripButton3.DropDownItems
                Dim item As New ToolStripMenuItem(
                     file, Nothing,
                     New EventHandler(
                        Sub(sender, e)
                            If file = FileSystem.OpenFile.Path Then Return

                            Dim title, content, ok, cancel As String
                            If Not IO.File.Exists(file) Then
                                title = Language("message_title", "file_error")
                                content = String.Format(Language("message_content", "file_not_exist"), file)

                                MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)

                                Recent.Remove(file)
                                Config.EditSetting("info", "recent", Join(Recent.ToArray, "|"))
                                Call ShowRecent()
                                Return
                            ElseIf FileSystem.IsEdit Then
                                title = Language("message_title", "open_file")
                                content = Language("message_content", "open_file_after_modify")
                                ok = Language("message", "open_file")
                                cancel = Language("message", "no_thanks")

                                If MsgBox(content, OkCancelDefault2, title, New MsgBoxOptions(MsgBoxOptions, ok, cancel)) = MsgBoxResult.Cancel Then
                                    Return
                                End If
                            ElseIf FileSystem.IsLoad Then
                                title = Language("message_title", "open_file")
                                content = Language("message_content", "open_file_after_open")
                                ok = Language("message", "open_file")
                                cancel = Language("message", "no_thanks")

                                If MsgBox(content, OkCancelDefault1, title, New MsgBoxOptions(MsgBoxOptions, ok, cancel)) = MsgBoxResult.Cancel Then
                                    Return
                                End If
                            End If

                            FileSystem.Open(file)
                            Call Open()
                        End Sub),
                     file)

                .Add(item)
            End With
        Next

        ToolStripButton6.DropDownItems.Clear()
        For Each file In Recent
            If Trim(file) = "" Then Continue For
            With ToolStripButton6.DropDownItems
                Dim item As New ToolStripMenuItem(
                     file, Nothing,
                     New EventHandler(
                        Sub(sender, e)
                            If file = FileSystem.ImportFile.Path Then Return

                            Dim title, content, ok, cancel As String
                            If Not IO.File.Exists(file) Then
                                title = Language("message_title", "file_error")
                                content = String.Format(Language("message_content", "file_not_exist"), file)

                                MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)

                                Recent.Remove(file)
                                Config.EditSetting("info", "recent", Join(Recent.ToArray, "|"))
                                Call ShowRecent()
                                Return
                            ElseIf FileSystem.IsEdit Then
                                title = Language("message_title", "import_file")
                                content = Language("message_content", "import_file_after_modify")
                                ok = Language("message", "import_file")
                                cancel = Language("message", "no_thanks")

                                If MsgBox(content, OkCancelDefault2, title, New MsgBoxOptions(MsgBoxOptions, ok, cancel)) = MsgBoxResult.Cancel Then
                                    Return
                                End If
                            End If

                            FileSystem.Import(file)
                            Call Import()
                        End Sub),
                     file)

                .Add(item)
            End With
        Next
    End Sub
    ''' <summary>
    ''' Set AutoComplate items
    ''' </summary>
    Private Sub SetAutoComplate()
        If menuThread IsNot Nothing AndAlso menuThread.IsAlive Then
            menuThread.Abort()
            menuThread.Interrupt()
        End If

        menuThread = New Threading.Thread(New Threading.ThreadStart(
        Sub()
            Dim tooltiptitle = Language("main", "autocomplate_tooltip_title")
            Dim tooltiptextDb = Language("main", "autocomplate_tooltip_text_db")
            Dim tooltiptextWork = Language("main", "autocomplate_tooltip_text_work")

            AutoCompleteMenu1.Clear()
            FileSystem.GetValid.ForEach(
            Sub(item)
                If Trim(item.Value.Target) <> "" AndAlso item.Value.Source <> item.Value.Target Then
                    AutoCompleteMenu1.AddItem(New WorkAutoComplateItem(item, tooltiptitle, tooltiptextWork))
                End If
            End Sub)

            If dbEnumerable Is Nothing Then
                dbEnumerable = DB.Data.Select(Of WorkAutoComplateItem)(
                Function(item) New WorkAutoComplateItem(item, tooltiptitle, tooltiptextDb))
            End If

            AutoCompleteMenu1.SetAutoCompleteItems(AutoCompleteMenu1.getAutoComplateItems().Concat(dbEnumerable))
            'Call SetAutoComplate()
        End Sub)) With {.IsBackground = True}
        menuThread.Start()
    End Sub
    ''' <summary>
    ''' Set state info
    ''' </summary>
    Private Sub ShowStatus()
        Dim state As State = FileSystem.GetState
        StatusLabel.Text = String.Format(Language("main_statusbar", "state"), state.Worked, state.Total, state.Rate, state.Unworked)
    End Sub
    ''' <summary>
    ''' Set new translation
    ''' </summary>
    ''' <param name="target">translation</param>
    Private Sub SetTranslate(target As String)
        If ListView1.SelectedIndices.Count = 0 Then Return

        With ListView1.SelectedItems(0)
            Dim index As Integer = .Text
            Dim source As String = .SubItems("Source").Text
            Dim value As String = .SubItems("Target").Text
            If value = target Then Return

            .SubItems.Item("Target").Text = target
            FileSystem.Work(index).Target = target
            FileSystem.Worked += If((source = value OrElse value = "") AndAlso source <> target AndAlso target <> "", 1, 0)
            FileSystem.Worked += If(source <> value AndAlso value <> "" AndAlso (source = target OrElse target = ""), -1, 0)
            '.ForeColor = If(source <> target AndAlso target <> "", Color.DarkGreen, Color.Black)

            FileSystem.IsEdit = True

            'Set status values
            Call ShowStatus()
        End With
    End Sub
    ''' <summary>
    ''' Select and focus listview control
    ''' </summary>
    Private Sub SelectListView()
        If ListView1.Items.Count = 0 Then Return
        If ListView1.SelectedIndices.Count = 0 Then
            ListView1.Items(0).Selected = True
        End If
        Dim item As ListViewItem = ListView1.SelectedItems(0)
        ListView1.EnsureVisible(item.Index)
        ListView1_ItemSelectionChanged(ListView1, New ListViewItemSelectionChangedEventArgs(item, item.Index, True))
    End Sub
    Private Delegate Sub GetSuggestionListDelegate(source As String)
    ''' <summary>
    ''' Get suggestion List
    ''' </summary>
    Private Sub GetSuggestionList(source As String)
        If thread IsNot Nothing Then thread.Abort() : thread.Interrupt()

        thread = New Threading.Thread(
        Sub()
            Application.DoEvents()
            'Dim translate As TranslateResult = getNetTranslation(source)
            Dim list As List(Of TranslatorIO.CompareResult) = GetSimilarityList(source, FileSystem.Work, DB.Data) ', 75, 60, 30, 20
            Dim from() As String = {Language("main", "source_from_0"), Language("main", "source_from_1"), Language("main", "source_from_2")}
            Dim key_1() As Keys = {Keys.NumPad1, Keys.NumPad2, Keys.NumPad3, Keys.NumPad4, Keys.NumPad5, Keys.NumPad6, Keys.NumPad7, Keys.NumPad8, Keys.NumPad9, Keys.NumPad0}
            Dim key_2() As Keys = {Keys.D1, Keys.D2, Keys.D3, Keys.D4, Keys.D5, Keys.D6, Keys.D7, Keys.D8, Keys.D9, Keys.D0}

            Invoke(New GetSuggestionListDelegate(
            Sub()
                SuggestList1.Clear()
                SuggestionsToolStripMenuItem.DropDownItems.Clear()
                SuggestionsToolStripMenuItem1.DropDownItems.Clear()

                Dim targetList As New List(Of String)
                For Each row In list
                    If targetList.Count > 9 Then Exit For
                    If targetList.Contains(row.Target) Then Continue For

                    SuggestList1.Add(
                        row.Target,
                        $"Ctrl+{targetList.Count + 1}",
                        Format(row.Rate, "0") & "%",
                        If(row.From < from.Length, from(row.From), from(0)),
                        RightToLeft.Yes,
                        New EventHandler(Sub() RichTextBox2.Text = row.Target)
                    )

                    With SuggestionsToolStripMenuItem.DropDownItems
                        .Add(New ToolStripMenuItem(
                                 row.Target, Nothing,
                                 New EventHandler(Sub() RichTextBox2.Text = row.Target),
                                 If(targetList.Count < key_1.Length, Keys.Control Or key_2(targetList.Count), Nothing)))
                    End With

                    With SuggestionsToolStripMenuItem1.DropDownItems
                        Dim ToolStripMenuItem = New ToolStripMenuItem(row.Target, Nothing,
                                New EventHandler(Sub() RichTextBox2.Text = row.Target), Keys.Control Or key_1(targetList.Count)) With {.ShowShortcutKeys = False}

                        .Add(ToolStripMenuItem)
                    End With

                    targetList.Add(row.Target)
                Next
                'AddNetTranslation(source, translate)
            End Sub), {source})
        End Sub) With {.IsBackground = True}
        thread.Start()
    End Sub
    ''' <summary>
    ''' Translate listview
    ''' </summary>
    ''' <param name="all">true is translate all item, false just translate untranslated item</param>
    Private Sub Translate(all As Boolean)
        'Dim Timer As New Stopwatch
        'Timer.Start()

        FileSystem.Worked = 0
        Dim mainTags As Integer() = {}
        Dim secondTags As Integer() = {}
        Dim tags As New TagsWindow(False)
        If tags.ShowDialog = DialogResult.OK Then
            mainTags = DB.GetTags(tags.CheckTags.ToArray).ToArray
            secondTags = DB.GetTags(tags.IndeterminateTags.ToArray).ToArray
        End If

        For Each Item As ListViewItem In ListView1.Items
            Dim source As String = Item.SubItems.Item("Source").Text
            Dim target As String = Item.SubItems.Item("Target").Text

            If all OrElse target = "" OrElse source = target Then
                Dim result As String = DB(source, True, mainTags, secondTags)
                target = If(result = "", source, result)
                Item.SubItems.Item("Target").Text = target
                FileSystem.Work(Val(Item.Text)).Target = target

                FileSystem.IsEdit = True
            End If

            FileSystem.Worked += If(target = "" OrElse source = target, 0, 1)
        Next

        Call SelectListView()
        Call ShowStatus()
        'Call SetAutoComplate()

        'Timer.Stop()
        'Dim Time As String = Nothing
        'If Timer.Elapsed.Hours > 0 Then Time &= Timer.Elapsed.Hours & "سائەت "
        'If Timer.Elapsed.Minutes > 0 Then Time &= Timer.Elapsed.Minutes & "مىنۇت "
        'If Timer.Elapsed.Seconds > 0 Then Time &= Timer.Elapsed.Seconds & "سېكونت "
        'If Timer.Elapsed.Milliseconds > 0 Then Time &= Timer.Elapsed.Milliseconds & "دەقىقە "

        MsgBox(Language("message_content", "translation_complated_local"), Language("message_title", "translation_complated"), MsgBoxOptions)
    End Sub
#End Region

#Region "Basic"
    Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        diff = Button2.Bottom - PictureBox1.Top
        Dim filters() As Filter = {
            New Filter(Language("file", "all_file"), {".xls", ".xlsx", ".lng", ".ini", ".ini1", ".srt", ".ass", ".xtf", ".UDraft"}, False),
            New Filter(Language("file", "udraft_file"), ".UDraft"),
            New Filter(Language("file", "excel_file"), {".xls", ".xlsx"}, {".xls", ".xlsx", ".UDraft"}),
            New Filter(Language("file", "lng_file"), ".lng", {".lng", ".UDraft"}),
            New Filter(Language("file", "ini_file"), ".ini", {".ini", ".UDraft"}),
            New Filter(Language("file", "ini1_file"), ".ini1", {".ini1", ".UDraft"}),
            New Filter(Language("file", "srt_file"), ".srt", {".srt", ".xls", ".xlsx", ".UDraft"}),
            New Filter(Language("file", "ass_file"), ".ass", {".ass", ".UDraft"}),
            New Filter(Language("file", "xtf_file"), ".xtf", {".xtf", ".UDraft"})
        }
        FileSystem = New FileSystem(filters)
        FileSystem_FilterIndexChanged(FileSystem, New FilterEventArgs(FileSystem.OpenFilterIndex, True))

        'Set listview, slidebar, statusbar & dictionary 
        ShowNoColumnToolStripMenuItem.Checked = If(Val(Config("settings", "column_no", 1)) = 1, True, False)
        ShowKeyColumnToolStripMenuItem.Checked = If(Val(Config("settings", "column_key", 1)) = 1, True, False)
        ShowSlidebarToolStripMenuItem.Checked = If(Val(Config("settings", "slidebar", 1)) = 1, True, False)
        ShowStatusbarToolStripMenuItem.Checked = If(Val(Config("settings", "statusbar", 1)) = 1, True, False)
        ShowDictionaryToolStripMenuItem.Checked = If(Val(Config("settings", "dictionary", 1)) = 1, True, False)
        SortByFileOrderToolStripMenuItem.Checked = True
        ToolStripButton1.Checked = If(Val(Config("settings", "source_dir", R2L)) = 1, True, False)
        ToolStripButton2.Checked = If(Val(Config("settings", "target_dir", R2L)) = 1, True, False)

        Show_CheckedChanged(ShowNoColumnToolStripMenuItem, New EventArgs())
        Show_CheckedChanged(ShowKeyColumnToolStripMenuItem, New EventArgs())
        ShowSlidebarToolStripMenuItem_CheckedChanged(ShowSlidebarToolStripMenuItem, New EventArgs())
        ShowStatusbarToolStripMenuItem_CheckedChanged(ShowStatusbarToolStripMenuItem, New EventArgs())
        ShowDictionaryToolStripMenuItem_CheckedChanged(ShowDictionaryToolStripMenuItem, New EventArgs())
        ToolStripButton1_CheckedChanged(ToolStripButton1, New EventArgs())
        ToolStripButton2_CheckedChanged(ToolStripButton2, New EventArgs())

        'Set status values
        Call ShowStatus()
        Call ShowRecent()
        'Call SetAutoComplate()

        'Read commant
        'MsgBox(Join(Environment.GetCommandLineArgs(), vbCrLf))
        If CommandLine.Length > 0 AndAlso IO.File.Exists(CommandLine(0)) Then FileSystem.Open(CommandLine(0)) : Call Open()
    End Sub
    Private Sub Form2_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
        If e.Control AndAlso e.Shift AndAlso e.KeyCode = Keys.D1 Then Button3.PerformClick()
    End Sub
    Private Sub TableLayoutPanel6_SizeChanged(sender As Object, e As EventArgs) Handles TableLayoutPanel6.SizeChanged
        Dim visible As Boolean = TableLayoutPanel6.Height > diff + 10
        PictureBox1.Visible = visible
        Label3.Visible = visible
        Label4.Visible = visible
    End Sub
    Private Sub FileSystem_FilterIndexChanged(sender As Object, e As FilterEventArgs) Handles FileSystem.FilterIndexChanged
        Me.Text = String.Format(If(Not e.IsValid, Language("main", "title"), Language("main", "title_with_path")), FileSystem.OpenFile.Path)

        If Not e.IsChange Then Return
        Panel1.Visible = e.IsValid
        StatusLabel.Visible = e.IsValid
        TableLayoutPanel6.Visible = Not e.IsValid

        'File
        ImportToolStripMenuItem.Enabled = e.IsValid
        SaveToolStripMenuItem.Enabled = e.IsValid
        SaveAsToolStripMenuItem.Enabled = e.IsValid
        SaveDataToolStripMenuItem.Enabled = e.IsValid

        'Edit
        ClearTranslationToolStripMenuItem.Enabled = e.IsValid
        ClearAllTranslationToolStripMenuItem.Enabled = e.IsValid
        ClearAllUntranslationToolStripMenuItem.Enabled = e.IsValid
        CopyFromSourceTextToolStripMenuItem.Enabled = e.IsValid
        CopyAllFromSourceTextToolStripMenuItem.Enabled = e.IsValid
        CopyUntranslateFromSourceTextToolStripMenuItem.Enabled = e.IsValid
        FindToolStripMenuItem.Enabled = e.IsValid
        ReplaceToolStripMenuItem.Enabled = e.IsValid

        'View
        ShowNoColumnToolStripMenuItem.Enabled = e.IsValid
        ShowKeyColumnToolStripMenuItem.Enabled = e.IsValid
        SortByFileOrderToolStripMenuItem.Enabled = e.IsValid
        SortBySourceToolStripMenuItem.Enabled = e.IsValid
        SortByTranslationToolStripMenuItem.Enabled = e.IsValid
        ShowSlidebarToolStripMenuItem.Enabled = e.IsValid
        ShowDictionaryToolStripMenuItem.Enabled = e.IsValid

        'Tools
        TranslateAllFromLocalToolStripMenuItem.Enabled = e.IsValid
        TranslateUntranslationsFromLocalToolStripMenuItem.Enabled = e.IsValid

        'Go
        DoneAndNextToolStripMenuItem.Enabled = e.IsValid
        PreviousTranslationToolStripMenuItem.Enabled = e.IsValid
        NextTranslationToolStripMenuItem.Enabled = e.IsValid
        PreviousUnfinishedToolStripMenuItem.Enabled = e.IsValid
        NextUnfinishedToolStripMenuItem.Enabled = e.IsValid

        'Toolbar
        ToolStripButton6.Enabled = e.IsValid
        ToolStripButton7.Enabled = e.IsValid
        SaveDataToolStripMenuItem.Enabled = e.IsValid
        ToolStripSplitButton1.Enabled = e.IsValid
        ToolStripButton10.Enabled = e.IsValid

        Me.Refresh()
    End Sub
    Private Sub MainWindow_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        Dim title, content, ok, cancel As String
        If FileSystem.IsEdit AndAlso e.CloseReason <> CloseReason.ApplicationExitCall Then
            title = Language("message_title", "exit")
            content = Language("message_content", "exit_after_modify")
            ok = Language("message", "exit")
            cancel = Language("message", "no_thanks")

            If MsgBox(content, OkCancelDefault2, title, New MsgBoxOptions(MsgBoxOptions, ok, cancel)) = MsgBoxResult.Cancel Then
                e.Cancel = True
            End If
            Config.DeleteSetting("info", "last")
        ElseIf FileSystem.IsLoad AndAlso e.CloseReason <> CloseReason.ApplicationExitCall Then
            title = Language("message_title", "exit")
            content = Language("message_content", "exit_after_open")
            ok = Language("message", "exit")
            cancel = Language("message", "no_thanks")

            If MsgBox(content, OkCancelDefault2, title, New MsgBoxOptions(MsgBoxOptions, ok, cancel)) = MsgBoxResult.Cancel Then
                e.Cancel = True
            End If
            Config.DeleteSetting("info", "last")
        End If
    End Sub
    Private Sub Form2_FormClosed(sender As Object, e As FormClosedEventArgs) Handles MyBase.FormClosed
        Application.Exit()
    End Sub
#End Region

#Region "File menu"
    Private Sub Open()
        If FileSystem.OpenFilterIndex = -1 Then
            Dim title As String = Language("message_title", "file_error")
            Dim content As String = String.Format(Language("message_content", "file_not_support"), FileSystem.OpenFile.Path)
            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
            Return
        End If

        'Set recent
        Recent.Remove(FileSystem.OpenFile.Path)
        Recent.Insert(0, FileSystem.OpenFile.Path)
        If Recent.Count > 10 Then Recent.RemoveAt(Recent.Count - 1)
        Config.EditSetting("info", "recent", Join(Recent.ToArray, "|"))
        Call ShowRecent()

        'Read file
        FileSystem.Read()

        'Set highlight
        highlight.Rules = HighlightGroup.GetHighlightRules(Highlights, FileSystem.ValidFile.Extension)
    End Sub
    Private Sub Import()
        If ListView1.Items.Count = 0 Then Return

        If FileSystem.ImportFilterIndex = -1 Then
            Dim title As String = Language("message_title", "file_error")
            Dim content As String = String.Format(Language("message_content", "file_not_support"), FileSystem.OpenFile.Path)

            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
            Return
        End If

        'Set recent
        Recent.Remove(FileSystem.ImportFile.Path)
        Recent.Insert(0, FileSystem.ImportFile.Path)
        If Recent.Count > 10 Then Recent.RemoveAt(Recent.Count - 1)
        Config.EditSetting("info", "recent", Join(Recent.ToArray, "|"))
        Call ShowRecent()

        FileSystem.Import()
    End Sub
    Private Sub Open_Click(sender As Object, e As EventArgs) Handles OpenToolStripMenuItem.Click, ToolStripButton3.Click
        If sender Is ToolStripButton3 AndAlso ToolStripButton3.Pressed Then Return

        FileSystem.OpenDialog.Title = Language("main", "open_file_title")
        Dim result As DialogResult = FileSystem.OpenDialog.ShowDialog()
        If result = DialogResult.OK Then Call Open()
    End Sub
    Private Sub Import_Click(sender As Object, e As EventArgs) Handles ImportToolStripMenuItem.Click, ToolStripButton6.Click
        If ListView1.Items.Count = 0 Then Return
        If sender Is ToolStripButton6 AndAlso ToolStripButton6.Pressed Then Return

        FileSystem.ImportDialog.Title = Language("main", "import_file_title")
        Dim result As DialogResult = FileSystem.ImportDialog.ShowDialog()
        If result = DialogResult.OK Then Call Import()
    End Sub
    Private Sub Save_Click(sender As Object, e As EventArgs) Handles SaveToolStripMenuItem.Click, ToolStripButton7.Click
        If FileSystem.OpenFilterIndex = -1 Then
            Dim title As String = Language("message_title", "file_error")
            Dim content As String = String.Format(Language("message_content", "file_not_support"), FileSystem.OpenFile.Path)

            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
            Return
        End If

        FileSystem.Save()
    End Sub
    Private Sub SaveAs_Click(sender As Object, e As EventArgs) Handles SaveAsToolStripMenuItem.Click
        FileSystem.SaveDialog.Title = Language("main", "save_file_title")
        Dim result As DialogResult = FileSystem.SaveDialog.ShowDialog()
        If result = DialogResult.Cancel Then Return

        If FileSystem.SaveFilterIndex = -1 Then
            Dim title As String = Language("message_title", "file_error")
            Dim content As String = String.Format(Language("message_content", "save_file_not_support"), FileSystem.SaveFile.Extension)

            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
            Return
        End If

        FileSystem.SaveAs()
    End Sub
    Private Sub SaveData_Click(sender As Object, e As EventArgs) Handles SaveDataToolStripMenuItem.Click
        If FileSystem.OpenFilterIndex = -1 Then
            Dim title As String = Language("message_title", "file_error")
            Dim content As String = String.Format(Language("message_content", "file_not_support"), FileSystem.OpenFile.Path)

            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
            Return
        End If

        Dim tagArr() As String = {}
        Dim tags As New TagsWindow(Nothing, True, False)
        If tags.ShowDialog = DialogResult.OK Then tagArr = tags.CheckTags.ToArray

        DB.Add(FileSystem, tagArr, New EventHandler(Of CompleteEventArgs)(
               Sub(obj, arg)
                   Dim title As String
                   Dim content As String
                   If Not arg.State Then
                       title = Language("message_title", "save_error")
                       content = String.Format(Language("message_content", "save_data_error"), arg.Message)

                       MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
                   Else
                       title = Language("message_title", "save_data")
                       content = Language("message_content", "save_data")

                       MsgBox(content, title, MsgBoxOptions)
                   End If
               End Sub))
    End Sub

    Private Sub SettingsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SettingsToolStripMenuItem.Click, ToolStripButton8.Click
        SettingsWindow.ShowDialog()
        Call SetFonts()
        If ListView1.Items.Count > 0 Then
            highlight.Rules = HighlightGroup.GetHighlightRules(Highlights, FileSystem.ValidFile.Extension)
            Call highlight.Make(RichTextBox1, True)
            Call highlight.Make(RichTextBox2, True)
        End If
    End Sub

    Private Sub ExitToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub
#End Region

#Region "Edit menu"
    Private Sub ClearTranslationToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClearTranslationToolStripMenuItem.Click, ClearTranslationToolStripMenuItem1.Click
        If ListView1.SelectedIndices.Count = 0 Then Return
        With ListView1.SelectedItems(0)
            Dim index As Integer = .Text
            Dim source As String = .SubItems.Item("Source").Text
            Dim target As String = .SubItems.Item("Target").Text

            .SubItems.Item("Target").Text = ""
            FileSystem.Work(index).Target = ""
            '.ForeColor = If(source <> target AndAlso target <> "", Color.DarkGreen, Color.Black)

            If target <> "" Then FileSystem.IsEdit = True

            'Set edit area
            Call SelectListView()

            'Set status values
            Call ShowStatus()
        End With
    End Sub
    Private Sub ClearAllTranslationToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClearAllTranslationToolStripMenuItem.Click
        For Each item As ListViewItem In ListView1.Items
            Dim index As Integer = item.Text
            Dim source As String = item.SubItems.Item("Source").Text
            Dim target As String = item.SubItems.Item("Target").Text

            item.SubItems.Item("Target").Text = ""
            FileSystem.Work(index).Target = ""
            '.ForeColor = If(source <> target AndAlso target <> "", Color.DarkGreen, Color.Black)

            If target <> "" Then FileSystem.IsEdit = True
        Next

        'Set edit area
        Call SelectListView()

        'Set status values
        Call ShowStatus()
    End Sub
    Private Sub ClearAllUntranslationToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClearAllUntranslationToolStripMenuItem.Click
        For Each item As ListViewItem In ListView1.Items
            Dim index As Integer = item.Text
            Dim source As String = item.SubItems.Item("Source").Text
            Dim target As String = item.SubItems.Item("Target").Text
            If source <> target Then Continue For

            item.SubItems.Item("Target").Text = ""
            FileSystem.Work(index).Target = ""
            '.ForeColor = If(source <> target AndAlso target <> "", Color.DarkGreen, Color.Black)

            If target <> "" Then FileSystem.IsEdit = True
        Next

        'Set edit area
        Call SelectListView()

        'Set status values
        Call ShowStatus()
    End Sub
    Private Sub CopyFromSourceTextToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CopyFromSourceTextToolStripMenuItem.Click, CopyFromSourceTextToolStripMenuItem1.Click
        If ListView1.SelectedIndices.Count = 0 Then Return
        With ListView1.SelectedItems(0)
            Dim index As Integer = .Text
            Dim source As String = .SubItems.Item("Source").Text
            Dim target As String = .SubItems.Item("Target").Text

            .SubItems.Item("Target").Text = source
            FileSystem.Work(index).Target = source
            '.ForeColor = If(source <> target AndAlso target <> "", Color.DarkGreen, Color.Black)

            If target <> source Then FileSystem.IsEdit = True

            'Set edit area
            Call SelectListView()

            'Set status values
            Call ShowStatus()
        End With
    End Sub
    Private Sub CopyAllFromSourceTextToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CopyAllFromSourceTextToolStripMenuItem.Click
        For Each item As ListViewItem In ListView1.Items
            Dim index As Integer = item.Text
            Dim source As String = item.SubItems.Item("Source").Text
            Dim target As String = item.SubItems.Item("Target").Text

            item.SubItems.Item("Target").Text = source
            FileSystem.Work(index).Target = source
            '.ForeColor = If(source <> target AndAlso target <> "", Color.DarkGreen, Color.Black)

            If target <> source Then FileSystem.IsEdit = True
        Next

        'Set edit area
        Call SelectListView()

        'Set status values
        Call ShowStatus()
    End Sub
    Private Sub CopyUntranslateFromSourceTextToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CopyUntranslateFromSourceTextToolStripMenuItem.Click
        For Each item As ListViewItem In ListView1.Items
            Dim index As Integer = item.Text
            Dim source As String = item.SubItems.Item("Source").Text
            Dim target As String = item.SubItems.Item("Target").Text
            If target <> "" Then Continue For

            item.SubItems.Item("Target").Text = source
            FileSystem.Work(index).Target = source
            '.ForeColor = If(source <> target AndAlso target <> "", Color.DarkGreen, Color.Black)

            If target <> source Then FileSystem.IsEdit = True
        Next

        'Set edit area
        Call SelectListView()

        'Set status values
        Call ShowStatus()
    End Sub
    Private Sub FindToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles FindToolStripMenuItem.Click
        If ListView1.Items.Count = 0 Then Return
        If ListView1.SelectedIndices.Count = 0 Then Call SelectListView()

        If Not SearchWindow.Created Then SearchWindow.Show(Me)
        SearchWindow.Tag = "search"
        SearchWindow.Text = Language("search_replace", "search")
    End Sub
    Private Sub ReplaceToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ReplaceToolStripMenuItem.Click
        If ListView1.Items.Count = 0 Then Return
        If ListView1.SelectedIndices.Count = 0 Then Call SelectListView()

        If Not SearchWindow.Created Then SearchWindow.Show(Me)
        SearchWindow.Tag = "replace"
        SearchWindow.Text = Language("search_replace", "replace")
    End Sub
#End Region

#Region "View menu"
    Private Sub Show_CheckedChanged(sender As Object, e As EventArgs) Handles ShowNoColumnToolStripMenuItem.CheckedChanged, ShowKeyColumnToolStripMenuItem.CheckedChanged
        ListView1_SizeChanged(sender, e)
    End Sub
    Private Sub Sort_CheckedChanged(sender As Object, e As EventArgs) Handles SortByFileOrderToolStripMenuItem.CheckedChanged, SortByTranslationToolStripMenuItem.CheckedChanged, SortBySourceToolStripMenuItem.CheckedChanged
        If sender Is SortByFileOrderToolStripMenuItem AndAlso SortByFileOrderToolStripMenuItem.Checked Then
            SortBySourceToolStripMenuItem.Checked = False
            SortByTranslationToolStripMenuItem.Checked = False
        ElseIf sender Is SortBySourceToolStripMenuItem AndAlso SortBySourceToolStripMenuItem.Checked Then
            SortByFileOrderToolStripMenuItem.Checked = False
            SortByTranslationToolStripMenuItem.Checked = False
        ElseIf sender Is SortByTranslationToolStripMenuItem AndAlso SortByTranslationToolStripMenuItem.Checked Then
            SortByFileOrderToolStripMenuItem.Checked = False
            SortBySourceToolStripMenuItem.Checked = False
        End If

        If sender.Checked Then
            'FileSystem.CurrentIndex = If(ListView1.SelectedIndices.Count > 0, CType(ListView1.SelectedItems(0).Tag, Row).Number - 1, -1)
            FileSystem_ReadCompleted(FileSystem, New CompleteEventArgs(True, "", False))
        End If
    End Sub
    Private Sub ShowSlidebarToolStripMenuItem_CheckedChanged(sender As Object, e As EventArgs) Handles ShowSlidebarToolStripMenuItem.CheckedChanged, ToolStripButton10.Click
        Panel2.Visible = sender.Checked
        Splitter1.Visible = sender.Checked
        ToolStripButton10.Checked = sender.Checked
        ShowSlidebarToolStripMenuItem.Checked = sender.Checked
        ToolStripButton10.Image = If(sender.Checked, My.Resources.显示侧栏, My.Resources.隐藏侧栏)

        If actived Then Config.EditSetting("settings", "slidebar", If(sender.Checked, 1, 0))
    End Sub
    Private Sub ShowStatusbarToolStripMenuItem_CheckedChanged(sender As Object, e As EventArgs) Handles ShowStatusbarToolStripMenuItem.CheckedChanged
        StatusStrip1.Visible = ShowStatusbarToolStripMenuItem.Checked

        If actived Then Config.EditSetting("settings", "statusbar", If(ShowStatusbarToolStripMenuItem.Checked, 1, 0))
    End Sub
    Private Sub ShowDictionaryToolStripMenuItem_CheckedChanged(sender As Object, e As EventArgs) Handles ShowDictionaryToolStripMenuItem.CheckedChanged
        Splitter3.Visible = ShowDictionaryToolStripMenuItem.Checked
        TableLayoutPanel4.Visible = ShowDictionaryToolStripMenuItem.Checked
        TableLayoutPanel2.Dock = If(ShowDictionaryToolStripMenuItem.Checked, DockStyle.Top, DockStyle.Fill)

        If actived Then Config.EditSetting("settings", "dictionary", If(ShowDictionaryToolStripMenuItem.Checked, 1, 0))
    End Sub
#End Region

#Region "Tools menu"
    Private Sub TranslateAllFromLocalToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles TranslateAllFromLocalToolStripMenuItem.Click
        Call Translate(True)
    End Sub
    Private Sub TranslateUntranslationsFromLocalToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles TranslateUntranslationsFromLocalToolStripMenuItem.Click, ToolStripSplitButton1.Click
        Call Translate(False)
    End Sub
    Private Sub DictionaryToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DictionaryToolStripMenuItem.Click, ToolStripButton9.Click
        If Not DictionaryWindow.Created Then
            DictionaryWindow.Show()
        Else
            DictionaryWindow.BringToFront()
        End If
    End Sub
#End Region

#Region "Go menu"
    Private Sub DoneAndNextToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DoneAndNextToolStripMenuItem.Click
        NextUnfinishedToolStripMenuItem.PerformClick()
    End Sub
    Private Sub PreviousTranslationToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PreviousTranslationToolStripMenuItem.Click
        If ListView1.Items.Count = 0 Then Return
        If ListView1.SelectedIndices.Count = 0 Then
            ListView1.Items(0).Selected = True
        End If
        Dim item As ListViewItem = ListView1.SelectedItems(0)
        Select Case item.Index
            Case 0 : item = ListView1.Items(ListView1.Items.Count - 1)
            Case Else : item = ListView1.Items(item.Index - 1)
        End Select
        item.Selected = True
        ListView1.EnsureVisible(item.Index)
    End Sub
    Private Sub NextTranslationToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NextTranslationToolStripMenuItem.Click
        If ListView1.Items.Count = 0 Then Return
        If ListView1.SelectedIndices.Count = 0 Then
            ListView1.Items(0).Selected = True
        End If
        Dim item As ListViewItem = ListView1.SelectedItems(0)
        Select Case item.Index
            Case ListView1.Items.Count - 1 : item = ListView1.Items(0)
            Case Else : item = ListView1.Items(item.Index + 1)
        End Select
        item.Selected = True
        ListView1.EnsureVisible(item.Index)
    End Sub
    Private Sub PreviousUnfinishedToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PreviousUnfinishedToolStripMenuItem.Click
        If ListView1.Items.Count = 0 Then Return
        If ListView1.SelectedIndices.Count = 0 Then
            ListView1.Items(0).Selected = True
        End If
        Dim item As ListViewItem = ListView1.SelectedItems(0)
        For i = item.Index - 1 To 0 Step -1
            item = ListView1.Items(i)
            Dim source As String = item.SubItems("Source").Text
            Dim target As String = item.SubItems("Target").Text
            If source = target OrElse target = "" Then Exit For
        Next
        item.Selected = True
        ListView1.EnsureVisible(item.Index)
    End Sub
    Private Sub NextUnfinishedToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles NextUnfinishedToolStripMenuItem.Click
        If ListView1.Items.Count = 0 Then Return
        If ListView1.SelectedIndices.Count = 0 Then
            ListView1.Items(0).Selected = True
        End If
        Dim item As ListViewItem = ListView1.SelectedItems(0)
        For i = item.Index + 1 To ListView1.Items.Count - 1
            item = ListView1.Items(i)
            Dim source As String = item.SubItems("Source").Text
            Dim target As String = item.SubItems("Target").Text
            If source = target OrElse target = "" Then Exit For
        Next
        item.Selected = True
        ListView1.EnsureVisible(item.Index)
    End Sub
#End Region

#Region "Database menu"
    Private Sub ExportToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ExportToolStripMenuItem.Click
        With SaveFileDialog1
            .Title = Language("main", "export_db_title")
            .Filter = Language("file", "udb_file") & "|*.UDB"
            .FileName = "sherer_export_" & Now().ToString("yyyyMMddHHmm")
            If .ShowDialog = DialogResult.OK Then
                DB.SaveAs(.FileName, New EventHandler(Of CompleteEventArgs)(
                    Sub(obj, arg)
                        Dim title As String
                        Dim content As String
                        If Not arg.State Then
                            title = Language("message_title", "export_db_error")
                            content = String.Format(Language("message_content", "export_db_error"), arg.Message)

                            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
                        Else
                            title = Language("message_title", "export_db")
                            content = Language("message_content", "export_db")

                            MsgBox(content, title, MsgBoxOptions)
                        End If
                    End Sub))
            End If
        End With
    End Sub
    Private Sub ImportToolStripMenuItem1_Click(sender As Object, e As EventArgs) Handles ImportToolStripMenuItem1.Click
        With OpenFileDialog1
            .Title = Language("main", "import_db_title")
            .Filter = Language("file", "udb_file") & "|*.UDB"
            .FileName = ""
            If .ShowDialog = DialogResult.OK Then
                Dim database As New DataBase(.FileName)
                DB.Add(database.DataFile, New EventHandler(Of CompleteEventArgs)(
                    Sub(obj, arg)
                        Dim title As String
                        Dim content As String
                        If Not arg.State Then
                            title = Language("message_title", "import_db_error")
                            content = String.Format(Language("message_content", "import_db_error"), arg.Message)

                            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
                        Else
                            title = Language("message_title", "import_db")
                            content = Language("message_content", "import_db")
                            MsgBox(content, title, MsgBoxOptions)
                        End If
                    End Sub))
            End If
        End With
    End Sub
#End Region

#Region "Help menu"
    Private Sub AboutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AboutToolStripMenuItem.Click
        AboutWindow.ShowDialog()
    End Sub
#End Region

#Region "Complete Event"
    Private Sub FileSystem_ReadCompleted(sender As Object, e As CompleteEventArgs) Handles FileSystem.ReadCompleted
        If Not e.State Then
            If Not e.ShowMessage Then Return
            Dim title As String = Language("message_title", "read_file_error")
            Dim content As String = String.Format(Language("message_content", "read_file_error"), e.Message)

            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
            Return
        End If

        'Sort data
        Dim orderData As IOrderedEnumerable(Of KeyValuePair(Of Integer, Row))
        If SortByFileOrderToolStripMenuItem.Checked Then
            orderData = FileSystem.GetValid.OrderBy(Function(item) item.Key)
        ElseIf SortBySourceToolStripMenuItem.Checked Then
            orderData = FileSystem.GetValid.OrderBy(Function(item) item.Value.Source)
        ElseIf SortByTranslationToolStripMenuItem.Checked Then
            orderData = FileSystem.GetValid.OrderBy(Function(item) item.Value.Target)
        Else
            Return
        End If

        Dim selectedIndex As Integer = FileSystem.CurrentIndex
        If ListView1.Items.Count <> FileSystem.Count Then
            ListView1.Items.Clear()
            For Each item In orderData
                Dim row As Row = FileSystem.Work(item.Key)
                With ListView1.Items.Add(item.Key)
                    .Tag = row
                    .Name = "Index"

                    .SubItems.Add(row.Number).Name = "No"
                    .SubItems.Add(row.Key).Name = "Key"
                    .SubItems.Add(row.Source).Name = "Source"
                    .SubItems.Add(row.Target).Name = "Target"

                    .BackColor = If(.Index Mod 2 = 0, Color.FromArgb(250, 250, 250), Color.White)
                End With
            Next
        Else
            Dim index As Integer = 0
            For Each item In orderData
                Dim row As Row = FileSystem.Work(item.Key)
                With ListView1.Items(index)
                    .Tag = row
                    .Name = "Index"
                    .Text = row.Index

                    .SubItems("No").Text = row.Number
                    .SubItems("Key").Text = row.Key
                    .SubItems("Source").Text = row.Source
                    .SubItems("Target").Text = row.Target

                    .BackColor = If(.Index Mod 2 = 0, Color.FromArgb(250, 250, 250), Color.White)

                    If FileSystem.CurrentIndex = row.Number - 1 Then selectedIndex = .Index

                    index += 1
                End With
            Next
        End If

        If selectedIndex > -1 AndAlso ListView1.Items.Count > selectedIndex Then
            ListView1.Items(selectedIndex).Selected = True
        ElseIf ListView1.Items.Count > 0 Then
            ListView1.Items(0).Selected = True
        End If

        'Set status values
        Call ShowStatus()
        Call SelectListView()
        'Call SetAutoComplate()

        'Save last edit file path
        Config.EditSetting("info", "last", FileSystem.OpenFile.Path)

        Button1.PerformClick()
        ListView1_SizeChanged(sender, e)

        If ListView1.Items.Count > 0 AndAlso e.ShowMessage Then MsgBox(Language("message_content", "read_file"), Language("message_title", "read_file"), MsgBoxOptions)
    End Sub
    Private Sub FileSystem_ImportCompleted(sender As Object, e As CompleteEventArgs) Handles FileSystem.ImportCompleted
        If Not e.State Then
            Dim title As String = Language("message_title", "import_file_error")
            Dim content As String = String.Format(Language("message_content", "import_file_error"), e.Message)

            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
            Return
        End If

        For Each item As ListViewItem In ListView1.Items
            Dim index As Integer = item.Text
            Dim source As String = item.SubItems.Item("Source").Text
            Dim target As String = FileSystem.Work(index).Target

            item.SubItems.Item("Target").Text = target
            'item.ForeColor = If(source <> target AndAlso target <> "", Color.DarkGreen, Color.Black)
        Next

        'Set status values
        Call ShowStatus()
        Call SelectListView()
        'Call SetAutoComplate()

        If ListView1.Items.Count > 0 Then MsgBox(Language("message_content", "import_file"), Language("message_title", "import_file"), MsgBoxOptions)
    End Sub
    Private Sub FileSystem_SaveCompleted(sender As Object, e As CompleteEventArgs) Handles FileSystem.SaveCompleted
        If Not e.State Then
            Dim title As String = Language("message_title", "save_file_error")
            Dim content As String = String.Format(Language("message_content", "save_file_error"), e.Message)

            MsgBox(content, MsgBoxStyle.Critical, title, MsgBoxOptions)
            Return
        End If

        'Call SetAutoComplate()
        MsgBox(Language("message_content", "save_file"), Language("message_title", "save_file"), MsgBoxOptions)
    End Sub
#End Region

#Region "Listview Settings"
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        If Trim(RichTextBox1.Text) <> "" Then
            Button3.Enabled = False
        End If
    End Sub
    Private Sub ListView1_ItemSelectionChanged(sender As Object, e As ListViewItemSelectionChangedEventArgs) Handles ListView1.ItemSelectionChanged
        If Not e.IsSelected Then Return

        Dim source As String = e.Item.SubItems("Source").Text
        Dim target As String = e.Item.SubItems("Target").Text
        RichTextBox1.Text = source
        RichTextBox2.Text = target
        Button3.Enabled = True

        If ListView1.SelectedIndices.Count = 0 Then Return

        FileSystem.CurrentIndex = CType(e.Item.Tag, Row).Number - 1
        Call GetSuggestionList(source)
        Call SetAutoComplate()
    End Sub
    Private Sub ListView1_ColumnWidthChanging(sender As Object, e As ColumnWidthChangingEventArgs) Handles ListView1.ColumnWidthChanging
        e.Cancel = True
        e.NewWidth = ListView1.Columns(e.ColumnIndex).Width
    End Sub
    Private Sub ListView1_SizeChanged(sender As Object, e As EventArgs) Handles ListView1.SizeChanged
        If ShowNoColumnToolStripMenuItem.Checked Then
            ColumnNo.AutoResize(If(ListView1.Items.Count = 0, ColumnHeaderAutoResizeStyle.HeaderSize, ColumnHeaderAutoResizeStyle.ColumnContent))
        Else
            ColumnNo.AutoResize(ColumnHeaderAutoResizeStyle.None)
            ColumnNo.Width = 0
        End If

        If ShowKeyColumnToolStripMenuItem.Checked Then
            Dim _width As Integer = ColumnIndex.Width + ColumnNo.Width +
            SystemInformation.VerticalScrollBarWidth + 4
            ColumnKey.Width = (ListView1.Width - _width) / 100 * 20
        Else
            ColumnKey.Width = 0
        End If

        Dim width As Integer = ColumnIndex.Width + ColumnNo.Width + ColumnKey.Width +
            SystemInformation.VerticalScrollBarWidth + 4

        ColumnSource.Width = (ListView1.Width - width) / 100 * 50
        ColumnTarget.Width = ColumnSource.Width

        If actived AndAlso sender Is ShowNoColumnToolStripMenuItem Then Config.EditSetting("settings", "column_no", If(ShowNoColumnToolStripMenuItem.Checked, 1, 0))
        If actived AndAlso sender Is ShowKeyColumnToolStripMenuItem Then Config.EditSetting("settings", "column_key", If(ShowKeyColumnToolStripMenuItem.Checked, 1, 0))
    End Sub
    Private Sub ContextMenuStrip1_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
        e.Cancel = (ListView1.Items.Count = 0 OrElse ListView1.SelectedIndices.Count = 0)
    End Sub
#End Region

#Region "Editor"
    Private Sub ToolStripButton1_CheckedChanged(sender As Object, e As EventArgs) Handles ToolStripButton1.CheckedChanged
        Dim rtl As Integer = If(ToolStripButton1.Checked, 1, 0)
        RichTextBox1.RightToLeft = rtl
        ColumnSource.TextAlign = Math.Abs(rtl - R2L)
        ToolStripButton1.Image = If(ToolStripButton1.Checked, My.Resources.direction_rtl, My.Resources.direction_ltr)

        If actived Then Config.EditSetting("settings", "source_dir", rtl)
    End Sub
    Private Sub ToolStripButton2_CheckedChanged(sender As Object, e As EventArgs) Handles ToolStripButton2.CheckedChanged
        Dim rtl As Integer = If(ToolStripButton2.Checked, 1, 0)
        RichTextBox2.RightToLeft = rtl
        AutoCompleteMenu1.ToolTipRightToLeft = rtl
        ColumnTarget.TextAlign = Math.Abs(rtl - R2L)
        ToolStripButton1.Image = If(ToolStripButton1.Checked, My.Resources.direction_rtl, My.Resources.direction_ltr)

        If actived Then Config.EditSetting("settings", "target_dir", rtl)
    End Sub

    Private Sub ToolStripButton4_Click(sender As Object, e As EventArgs) Handles ToolStripButton4.Click
        FontDialog1.Font = RichTextBox1.Font
        If FontDialog1.ShowDialog() = DialogResult.OK Then
            RichTextBox1.Font = FontDialog1.Font
            Config.EditSetting("settings", "source_font", New FontConverter().ConvertToString(FontDialog1.Font))
        End If
    End Sub
    Private Sub ToolStripButton5_Click(sender As Object, e As EventArgs) Handles ToolStripButton5.Click
        FontDialog1.Font = RichTextBox2.Font
        If FontDialog1.ShowDialog() = DialogResult.OK Then
            RichTextBox2.Font = FontDialog1.Font
            AutoCompleteMenu1.Font = FontDialog1.Font
            AutoCompleteMenu1.ToolTipFont = FontDialog1.Font
            With FontDialog1.Font
                AutoCompleteMenu1.ToolTipTitleFont = New Font(.FontFamily, .Size, FontStyle.Bold, .Unit)
            End With
            Config.EditSetting("settings", "target_font", New FontConverter().ConvertToString(FontDialog1.Font))
        End If
    End Sub

    Private Sub ToolStripSplitButton2_MouseUp(sender As Object, e As MouseEventArgs) Handles ToolStripSplitButton2.MouseUp
        If ToolStripSplitButton2.Pressed Then Return
        If TypeOf sender.Tag Is ToolStripMenuItem Then Call InsertCharacters_MouseUp(sender.Tag, e)
    End Sub
    Private Sub InsertCharacters_MouseUp(sender As Object, e As MouseEventArgs) Handles LefttorightEmbeddingToolStripMenuItem.MouseUp, RighttoleftEmbeddingToolStripMenuItem.MouseUp, RighttoleftMarkToolStripMenuItem.MouseUp, LefttorightMarkToolStripMenuItem.MouseUp
        If TypeOf sender.Tag IsNot String OrElse String.IsNullOrEmpty(sender.Tag) Then Return

        Select Case e.Button
            Case MouseButtons.Left
                With RichTextBox2
                    Dim start As Integer = .SelectionStart
                    Dim length As Integer = .SelectionLength
                    .SelectionStart = 0
                    .SelectionLength = 0
                    .SelectedText = sender.Tag
                    .SelectionStart = start
                    .SelectionLength = length
                End With
            Case MouseButtons.Right
                With RichTextBox2
                    Dim start As Integer = .SelectionStart
                    Dim length As Integer = .SelectionLength
                    .SelectionLength = 0
                    .SelectedText = sender.Tag
                    .SelectionLength = length
                End With
        End Select

        ToolStripSplitButton2.Tag = sender
        For Each item In ToolStripSplitButton2.DropDownItems
            item.Checked = (sender.Name = item.Name)
        Next
    End Sub

    Private Sub RichTextBox1_TextChanged(sender As Object, e As EventArgs) Handles RichTextBox1.TextChanged
        lighting = True
        Call highlight.Make(CType(sender, RichTextBox), True)
        lighting = False
    End Sub
    Private Sub RichTextBox2_TextChanged(sender As Object, e As EventArgs) Handles RichTextBox2.TextChanged
        Call highlight.Make(CType(sender, RichTextBox), True)
        Call SetTranslate(RichTextBox2.Text)
    End Sub

    Private Sub RichTextBox1_SelectionChanged(sender As Object, e As EventArgs) Handles RichTextBox1.SelectionChanged
        If lighting Then Return
        TextBox1.Text = RichTextBox1.SelectedText
        Button1.PerformClick()
    End Sub

    Private Sub ContextMenuStrip2_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip2.Opening
        Dim rich As RichTextBox = sender.SourceControl
        CutToolStripMenuItem.Enabled = Not rich.ReadOnly AndAlso rich.SelectionLength > 0
        CopyToolStripMenuItem.Enabled = rich.SelectionLength > 0
        PasteToolStripMenuItem.Enabled = Not rich.ReadOnly AndAlso rich.CanPaste(DataFormats.GetFormat(DataFormats.Text))
        DeleteToolStripMenuItem.Enabled = Not rich.ReadOnly AndAlso rich.SelectionLength > 0
        SelectAllToolStripMenuItem.Enabled = rich.TextLength > 0
        SearchWithGoogleToolStripMenuItem.Enabled = rich.SelectionLength > 0
    End Sub
    Private Sub CutToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CutToolStripMenuItem.Click
        Dim rich As RichTextBox = ContextMenuStrip2.SourceControl
        rich.Cut()
    End Sub
    Private Sub CopyToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles CopyToolStripMenuItem.Click
        Dim rich As RichTextBox = ContextMenuStrip2.SourceControl
        rich.Copy()
    End Sub
    Private Sub PasteToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PasteToolStripMenuItem.Click
        Dim rich As RichTextBox = ContextMenuStrip2.SourceControl
        rich.Paste(DataFormats.GetFormat(DataFormats.Text))
    End Sub
    Private Sub DeleteToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles DeleteToolStripMenuItem.Click
        Dim rich As RichTextBox = ContextMenuStrip2.SourceControl
        rich.SelectedText = ""
    End Sub
    Private Sub SelectAllToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SelectAllToolStripMenuItem.Click
        Dim rich As RichTextBox = ContextMenuStrip2.SourceControl
        rich.SelectAll()
    End Sub
    Private Sub SearchWithGoogleToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SearchWithGoogleToolStripMenuItem.Click
        Dim info = getTranslateInfo()
        Dim rich As RichTextBox = ContextMenuStrip2.SourceControl
        Process.Start($"https://translate.google.cn/?sl={info.Key}&tl={info.Value}&text={rich.SelectedText}&op=translate")
    End Sub
#End Region

#Region "Dictionary"
    Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
        If e.KeyCode = Keys.Enter Then
            Button1.PerformClick()
            e.SuppressKeyPress = True
        End If
    End Sub
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim key As String = Trim(TextBox1.Text)
        Dim Dt As New DataTable
        Dt.Columns.Add("No")
        Dt.Columns.Add("Source")
        Dt.Columns.Add("Target")

        If key <> "" Then
            For Each row In FileSystem.GetContainsList(key)
                Dt.Rows.Add({row.Value.Number, row.Value.Source, row.Value.Target})
            Next
        End If

        DataGridView1.DataSource = Dt
        DataGridView1.Columns.Item("No").Visible = False
        DataGridView1.Columns.Item("Source").Visible = False
        DataGridView1.Columns.Item("Target").HeaderText = Language("main_listview_column", "target")
    End Sub
    Private Sub DataGridView1_CellEnter(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellEnter, DataGridView1.CellMouseEnter
        If e.RowIndex = -1 Then Return
        DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).ToolTipText = DataGridView1.Rows(e.RowIndex).Cells("No").Value.ToString & vbCrLf & DataGridView1.Rows(e.RowIndex).Cells("Source").Value.ToString
    End Sub
#End Region

#Region "AutoComplateMenu"
    Class CustomAutoComplateMenu
        Inherits AutoCompleteMenu

        Public Overrides Function CanAddItem(items As IEnumerable(Of AutoCompleteItem), item As AutoCompleteItem) As Boolean
            If Not MyBase.CanAddItem(items, item) Then Return False
            If items Is Nothing Then Return True
            Return items.Count(Function(match) Trim(match.ToString).ToLower = Trim(item.ToString).ToLower) = 0
        End Function
        Public Overrides Function CanAddVisibleItem(items As List(Of AutoCompleteItem), item As AutoCompleteItem) As Boolean
            If Not MyBase.CanAddItem(items, item) Then Return False
            If items Is Nothing Then Return True
            Return items.FindIndex(Function(match) Trim(match.ToString).ToLower = Trim(item.ToString).ToLower) = -1
        End Function
        Public Overrides Function SortList(list As List(Of AutoCompleteItem), str As String, ByRef selectedIndex As Integer) As List(Of AutoCompleteItem)
            If selectedIndex > -1 Then selectedIndex = 0
            Return list.OrderBy(
                Function(item)
                    If item.ToString().ToLower = str.ToLower Then
                        Return 0
                    ElseIf item.ToString.ToLower.StartsWith(str.ToLower) Then
                        Return 1
                    Else
                        Return 2
                    End If
                End Function).ThenBy(
                Function(item)
                    If (TypeOf item Is WorkAutoComplateItem) Then
                        Select Case CType(item, WorkAutoComplateItem).Type
                            Case WorkAutoComplateItem.DataType.Data : Return 2
                            Case WorkAutoComplateItem.DataType.Row : Return 1
                            Case Else : Return 3
                        End Select
                    Else Return 3
                    End If
                End Function).ToList
        End Function
    End Class

    Class WorkAutoComplateItem
        Inherits AutoCompleteItem

        Public Enum DataType
            Row = 0
            Data = 1
        End Enum
        Public Type As DataType
        Private _tooltipText As String
        Private _tooltipTitle As String
        Public Row As KeyValuePair(Of Integer, Row)
        Public Data As KeyValuePair(Of String, List(Of DataValue))
        Public Sub New(row As KeyValuePair(Of Integer, Row), tooltipTitle As String, tooltipText As String)
            MyBase.New(row.Value.Target)

            Me.Row = row
            Me.Type = DataType.Row
            Me._tooltipText = tooltipText
            Me._tooltipTitle = tooltipTitle
        End Sub
        Public Sub New(data As KeyValuePair(Of String, List(Of DataValue)), tooltipTitle As String, tooltipText As String)
            MyBase.New(data.Key)

            Me.Data = data
            Me.Type = DataType.Data
            Me._tooltipText = tooltipText
            Me._tooltipTitle = tooltipTitle
        End Sub

        Public Overrides Property ToolTipText As String
            Get
                If Type = DataType.Row Then
                    Return String.Format(_tooltipText, Me.Row.Value.Number, Me.Row.Value.Target, Me.Row.Value.Source)
                ElseIf Type = DataType.Data Then
                    Return String.Format(_tooltipText, Me.Data.Key, Me.Data.Value(0).Value)
                Else
                    Return Me.ToString()
                End If
            End Get
            Set(value As String)
                MyBase.ToolTipText = value
            End Set
        End Property
        Public Overrides Property ToolTipTitle As String
            Get
                Return String.Format(_tooltipTitle, Me.MenuText)
            End Get
            Set(value As String)
                MyBase.ToolTipTitle = value
            End Set
        End Property

        Public Overrides Function GetTextForReplace() As String
            Return Me.MenuText
        End Function

        Public Overrides Function Compare(fragmentText As String) As AutoCompleteMenuNS.CompareResult
            Dim text As String = Nothing
            For Each match As Match In Regex.Matches(Me.Text, "\b\w+\b")
                If match.Value.StartsWith(fragmentText, StringComparison.CurrentCultureIgnoreCase) Then
                    Me.MenuText = match.Value
                    Return AutoCompleteMenuNS.CompareResult.VisibleAndSelected
                ElseIf match.Value.ToLower.Contains(fragmentText.ToLower) Then
                    text = match.Value
                End If
            Next

            If String.IsNullOrEmpty(text) Then
                Return AutoCompleteMenuNS.CompareResult.Hidden
            Else
                Me.MenuText = text
                Return AutoCompleteMenuNS.CompareResult.Visible
            End If
        End Function
    End Class
#End Region

End Class